package com.example.mykotlinapp

/**
 *
 *
 * @author zhudeshuai
 * @since 2019/7/19
 */

//泛型

//类型参数约束

private fun test150() {
    val list = listOf(1, 2, 3, 4)
    val list2 = listOf(1.2, 3.2, 4.3, 1.3)
    val list3 = listOf("A", "B", "C")

    list.sum()
    list2.sum()
}

//为类型形参指定多个约束

interface IA {
    fun A()
}

interface IB {
    fun B()
}

fun <T> ensureTrailingPeriod(seq: T) where T : IA, T : IB {
    println(seq.javaClass)
}

class RC : IB, IA {
    override fun A() {
    }

    override fun B() {
    }

}

private fun test151() {
    val rc = RC()
    print(ensureTrailingPeriod(rc))
}


//声明带实化类型参数的函数 inline
//fun <T> isA(value: Any) = value is T 无法检查一个可擦除类型

inline fun <reified T> isA(value: Any) = value is T

private fun test152() {
    val list = listOf("A", 2, "B", 3, "C")
    println(list.filterIsInstance<String>())
}


//协变：保留子类型变化关系   out

open class N {

}

open class Animal:N() {
    fun feed() {

    }
}

class Herd<in T : N> {//注意out修饰的泛型只能出现在out位置（返回值）, in修饰的泛型只能出现在in位置（参数）

}

fun feedAll(animals: Herd<Animal>) {

}

class Cat : Animal() {

}



fun test153(f: (Cat) -> Number){

}


fun Animal.getIndex():Int = 6

private fun main() {
    val herd = Herd<N>()
    feedAll(herd)

    test153(Animal::getIndex)
}